home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_9.zip / INTA.C < prev    next >
C/C++ Source or Header  |  1993-07-27  |  51KB  |  2,255 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. /* interpreter procedures - interpreter part a */
  11.  
  12.  
  13. /* Include standard header modules */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "config.h"
  17. #include "int.h"
  18. #include "ivars.h"
  19. #include "farithp.h"
  20. #include "predefp.h"
  21. #include "machinep.h"
  22. #include "taskingp.h"
  23. #include "imiscp.h"
  24. #include "intbp.h"
  25. #include "intcp.h"
  26. #include "intap.h"
  27.  
  28. static int main_loop();
  29. static int get_word();
  30. #ifdef DEBUG_INT
  31. static void zbreak(int);
  32. #endif
  33.  
  34. #define TRACE
  35. /* MAIN PROGRAM */
  36.  
  37. #ifdef DEBUG_STORES
  38. int *heap_store_addr;
  39. /* set heap_store_offset non zero to trace stores to that offset
  40.  * in primary heap 
  41.  */
  42. extern int heap_store_offset;
  43. int heap_store_now=0;
  44. #endif
  45.  
  46. int int_main()                                                /*;int_main*/
  47. {
  48.     int        status;
  49.  
  50.     reset_clock();
  51.     num_cunits = 0;
  52.  
  53.     /* Memory initialization, allocate primary heap segment. */
  54.  
  55.     if(!allocate_new_heap()) {
  56.         fprintf(stderr,"Unable to allocate primary heap\n");
  57.         exit(RC_ABORT);
  58.     }
  59.  
  60.     /* Initialize working template for fixed point arithmetic */
  61.  
  62.     *heap_next++ = 1 + WORDS_PTR + WORDS_FX_RANGE;
  63.     heap_next += WORDS_PTR;
  64.     temp_template = FX_RANGE(heap_next);
  65.     temp_template->ttype = TT_FX_RANGE;
  66.     temp_template->object_size = 2;
  67.     temp_template->small_exp_2 = 0;
  68.     temp_template->small_exp_5 = 0;
  69.     temp_template->fxlow = MIN_LONG;
  70.     temp_template->fxhigh = MAX_LONG;
  71.     heap_next += WORDS_FX_RANGE;
  72.  
  73.     /* Other initialization */
  74.  
  75.     sfp = bfp = 0;
  76.     initialize_predef();
  77.     initialize_tasking();
  78.  
  79.     /* Perform the main loop of the interpretor(terminates at end of pgm) */
  80.  
  81.     status = main_loop();
  82.  
  83.     /* Termination processing */
  84.  
  85.     predef_term();
  86.  
  87.     return status;
  88. }
  89.  
  90. /*
  91.  *  MAIN LOOP
  92.  *  =========
  93.  */
  94.  
  95. /*
  96.  *  GET_BYTE        Next code byte (char), IP is incremented
  97.  *  GET_WORD        Next code word (int), IP is incremented
  98.  *  GET_GAD(bse,off)    Get base/offset from code, IP incremented
  99.  *  GET_LAD(bse,off)    Get local addr from code, and get corr global addr
  100.  */
  101. #define GET_BYTE      (0xff & (int)cur_code[ip++])
  102. #ifdef ALIGN_WORD
  103. #define GET_WORD      (w=get_word(), w)
  104. #else
  105. #define GET_WORD          (w = *((int *)(cur_code+ip)), ip += sizeof(int), w)
  106. #endif
  107. #define GET_GAD(bse,off)  bse=GET_BYTE,off=GET_WORD
  108. #define GET_LAD(bse,off)  sp=GET_WORD+sfp,bse=cur_stack[sp],off=cur_stack[sp+1]
  109.  
  110. static int main_loop()                                            /*;main_loop*/
  111. {
  112. #ifdef DEBUG_INT
  113.     int     iparg;
  114. #endif
  115. #ifdef ALIGN_WORD
  116.     /* auxiliary procedures if must unpack from code stream byte by byte */
  117. #endif
  118.  
  119.     /* General purpose work locations */
  120.  
  121.     /* Loop through instructions */
  122.  
  123.     for (;;) {
  124.  
  125. #ifdef GWUMON
  126.         /*  Calculate task timing for each task, one tick is one */
  127.         /*  pass through the loop */
  128.  
  129.         CWK_TIME_TASK();
  130. #endif
  131.         /* Simulate the Clock Interrupt */
  132.  
  133.         if (next_clock_flag &&(next_clock <(now_time = itime() + time_offset)))
  134.             clock_interrupt(now_time);
  135.  
  136.         /* Round-robin scheme: next task's turn ? */
  137.  
  138.         if (rr_flag && (rr_counter++ > rr_nb_max_stmts))
  139.             round_robin();
  140.  
  141. #ifdef DEBUG_INT
  142. #ifdef DEBUG_STORES
  143.         if (heap_store_offset!=0 && 
  144.           heap_store_now != heap_store_addr[heap_store_offset]) {
  145.             printf("heap stores change %d from %d to %d\n",
  146.               heap_store_offset, heap_store_now, 
  147.               heap_store_addr[heap_store_offset]);
  148.             heap_store_now = heap_store_addr[heap_store_offset];
  149.         }
  150. #endif
  151.         iparg = ip;
  152.         if (instruction_trace)
  153.             i_list1(&iparg, cur_code);        /* debug */
  154.         if(break_point && (ip >= break_point))
  155.             zbreak(0);
  156. #endif
  157.         /* Get next opcode, bump instruction pointer and switch to routine */
  158.         switch(GET_BYTE) {
  159.  
  160.         case I_NOP:
  161.             break;
  162.  
  163.             /* Instructions Dealing with Tasking */
  164.  
  165.         case I_ABORT:
  166.             value = GET_WORD;            /* number of tasks in stack */
  167.             abort(value);
  168.             break;
  169.  
  170.         case I_ACTIVATE:
  171.             if (BLOCK_FRAME->bf_tasks_declared != 0) {
  172.                 value = pop_task_frame();
  173.                 start_activation(value, tp, bfp);
  174.                 /* master is current block frame */
  175.             }
  176.             break;
  177.  
  178.         case I_ACTIVATE_NEW_L:
  179.             GET_LAD(bse, off);
  180.             if (BLOCK_FRAME->bf_tasks_declared != 0) {
  181.                 value = pop_task_frame();
  182.                 ptr = ADDR(bse, off);
  183.                 start_activation(value, ACCESS(ptr)->master_task, 
  184.                   ACCESS(ptr)->master_bfp);
  185.             }
  186.             break;
  187.  
  188.         case I_ACTIVATE_NEW_G:
  189.             GET_GAD(bse, off);
  190.             if (BLOCK_FRAME->bf_tasks_declared != 0) {
  191.                 value = pop_task_frame();
  192.                 ptr = ADDR(bse, off);
  193.                 start_activation(value, ACCESS(ptr)->master_task, 
  194.                   ACCESS(ptr)->master_bfp);
  195.             }
  196.             break;
  197.  
  198.         case I_CREATE_TASK_G:
  199.             GET_GAD(bse, off);
  200.             start_creation(bse, off);
  201.             break;
  202.  
  203.         case I_CREATE_TASK_L:
  204.             GET_LAD(bse, off);
  205.             start_creation(bse, off);
  206.             break;
  207.  
  208.         case I_POP_TASKS_DECLARED_G:
  209.             GET_GAD(bse, off);
  210.             if (BLOCK_FRAME->bf_tasks_declared != 0)
  211.                 value = pop_task_frame();
  212.             else
  213.                 value = 0;
  214.             *ADDR(bse, off) = value;
  215.             break;
  216.  
  217.         case I_POP_TASKS_DECLARED_L:
  218.             GET_LAD(bse, off);
  219.             if (BLOCK_FRAME->bf_tasks_declared != 0)
  220.                 value = pop_task_frame();
  221.             else
  222.                 value = 0;
  223.             *ADDR(bse, off) = value;
  224.             break;
  225.  
  226.         case I_LINK_TASKS_DECLARED:
  227.             POP(value);
  228.             push_task_frame(value);
  229.             break;
  230.  
  231.         case I_CURRENT_TASK:
  232.             PUSH(tp);
  233.             break;
  234.  
  235.         case I_END_ACTIVATION:
  236.             value = GET_BYTE;
  237.             end_activation(value);    /* 0=error during activation, 1=ok */
  238.             break;
  239.  
  240.         case I_END_RENDEZVOUS:
  241.             end_rendezvous();
  242.             break;
  243.  
  244.         case I_ENTRY_CALL:
  245.             value = GET_WORD;        /* retrieve parameter from code */
  246.             entry_call((long) ENDLESS,value);
  247.             break;
  248.  
  249.         case I_RAISE_IN_CALLER:
  250.             raise_in_caller();
  251.             break;
  252.  
  253.         case I_SELECTIVE_WAIT:
  254.             value = GET_WORD;        /* number of alternatives */
  255.  
  256.             /* if = 0 then it is a simple accept, entry addr is on stack. */
  257.             /* else: alternative descriptors on to of stack are scanned by */
  258.             /*   the procedure, which leaves the index of the chosen one.  */
  259.  
  260.             selective_wait(value);
  261.             break;
  262.  
  263.         case I_TERMINATE:
  264.             purge_rdv(tp);
  265.             value = GET_BYTE;
  266.             deallocate(BLOCK_FRAME->bf_data_link);
  267.  
  268.             /* bf_tasks_declared always null here */
  269.  
  270.             switch(value) {
  271.  
  272.             case 0: /* task terminates because reaches the end */
  273.                 break;
  274.  
  275.             case 1: /* task terminates because of terminate alternative */
  276.                 break;
  277.  
  278.             case 2:
  279.                 value = 0;
  280. #ifdef GWUMON
  281.                 {
  282.                 char msg[240];
  283.                 sprintf(msg,"task %d terminated due to unhandled exception: %s\n"
  284.                       ,tp,exception_slots[exr]);
  285.                 CWK_Exception_Raised( tp, msg );
  286.                 }
  287. #else
  288.                 if (exception_trace)
  289.                     printf("task %d terminated due to unhandled exception: %s\n"
  290.                       ,tp,exception_slots[exr]);
  291. #endif
  292.                 break;
  293.  
  294.             case 3:
  295.                 printf("unhandled exception in library unit %s\n",
  296.                   exception_slots[exr]);
  297.                 return RC_ERRORS;
  298.  
  299.             case 4:
  300.                 printf("main task terminated due to unhandled exception %s\n",
  301.                   exception_slots[exr]);
  302.                 printf("propagated from %s",code_slots[raise_cs]);
  303.                 if (raise_lin) printf(" at line %d",raise_lin);
  304.                 printf(" (%s)\n",raise_reason);
  305.                 return RC_ERRORS;
  306.  
  307.             case 5: /* normal end of main */
  308.                 return RC_SUCCESS;
  309.  
  310.             case 6: /* dead-lock */
  311.                 printf("dead-lock: system inactive\n");
  312.                 return RC_ERRORS;
  313.             }
  314.             complete_task();
  315.             break;
  316.  
  317.         case I_TIMED_ENTRY_CALL:
  318.             POPL(lvalue);
  319.             /* retrieve length of parameter table from code */
  320.             entry_call((lvalue >= 0) ? lvalue : (long) 0, GET_WORD);
  321.             break;
  322.  
  323.         case I_WAIT:     /* delay */
  324.             POPL(lvalue);
  325.             delay_stmt(lvalue);
  326.             break;
  327.  
  328.             /* Instructions for Memory Allocation */
  329.  
  330.         case I_CREATE_B:
  331.         case I_CREATE_W:
  332.             create(1, &bse, &off, &ptr);
  333.             PUSH_ADDR(bse, off);
  334.             break;
  335.  
  336.         case I_CREATE_L:
  337.             create(WORDS_LONG, &bse, &off, &ptr);
  338.             PUSH_ADDR(bse, off);
  339.             break;
  340.  
  341.         case I_CREATE_A:
  342.             create(2, &bse, &off, &ptr);
  343.             PUSH_ADDR(bse, off);
  344.             break;
  345.  
  346.         case I_CREATE_STRUC:
  347.             create_structure();
  348.             break;
  349.  
  350.         case I_CREATE_COPY_STRUC:
  351.             creat